package com.bigfans.orderservice.api;

import com.bigfans.framework.Applications;
import com.bigfans.framework.CurrentUser;
import com.bigfans.framework.annotations.NeedLogin;
import com.bigfans.framework.kafka.KafkaTemplate;
import com.bigfans.framework.model.PageBean;
import com.bigfans.framework.model.PageContext;
import com.bigfans.framework.web.BaseController;
import com.bigfans.framework.web.RestResponse;
import com.bigfans.model.dto.order.OrderPricingDto;
import com.bigfans.model.dto.order.OrderPricingResultDto;
import com.bigfans.model.dto.order.OrderItemPricingDto;
import com.bigfans.model.dto.order.OrderItemPricingResultDto;
import com.bigfans.orderservice.api.clients.CartServiceClient;
import com.bigfans.orderservice.api.clients.PricingServiceClient;
import com.bigfans.orderservice.api.clients.UserServiceClient;
import com.bigfans.orderservice.api.form.OrderCreateForm;
import com.bigfans.orderservice.api.form.OrderCreateItemForm;
import com.bigfans.orderservice.exception.OrderCreateException;
import com.bigfans.orderservice.model.*;
import com.bigfans.orderservice.service.OrderItemService;
import com.bigfans.orderservice.service.OrderService;
import com.bigfans.orderservice.service.PayMethodService;
import com.bigfans.orderservice.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author lichong
 * @create 2018-02-17 下午12:25
 **/
@RestController
public class OrderApi extends BaseController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private PayMethodService payMethodService;
    @Autowired
    private ProductService productService;
    @Autowired
    private CartServiceClient cartServiceClient;
    @Autowired
    private PricingServiceClient pricingServiceClient;
    @Autowired
    private UserServiceClient userServiceClient;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @PostMapping(value = "/order")
    @NeedLogin
    public RestResponse createOrder(@RequestBody OrderCreateForm orderForm) throws Exception {
        CurrentUser currentUser = Applications.getCurrentUser();
        String addressId = orderForm.getAddressId();
        CompletableFuture<Address> myAddressFuture = userServiceClient.myAddress(currentUser , addressId);

        OrderPricingDto calculateDto = new OrderPricingDto();
        calculateDto.setUsedCouponId(orderForm.getUsedCouponId());
        calculateDto.setUsedPoints(orderForm.getUsedPoints());
        calculateDto.setUserId(currentUser.getUid());

        List<OrderCreateItemForm> orderFormItems = orderForm.getItems();
        for (OrderCreateItemForm item : orderFormItems) {
            OrderItemPricingDto itemCalculateDto = new OrderItemPricingDto();
            itemCalculateDto.setProdId(item.getProdId());
            itemCalculateDto.setQuantity(item.getQuantity());
            calculateDto.addItem(itemCalculateDto);
        }
        // 计算订单
        CompletableFuture<OrderPricingResultDto> resultDtoFuture = pricingServiceClient.calculateOrder(currentUser , calculateDto);

        Order order = new Order();
        Address address = myAddressFuture.get();
        // 设置收货人信息
        order.setAddressId(addressId);
        order.setAddressConsignee(address.getConsignee());
        order.setAddressDetail(address.getAddress());
        order.setAddressPhone(address.getPhone());
        order.setUserId(currentUser.getUid());

        // 付款方式
        PayMethod payMethod = payMethodService.getByCode(orderForm.getPayMethodCode());
        order.setPayMethodName(payMethod.getName());
        order.setPayMethodCode(payMethod.getCode());

        // 计算订单价格
        OrderPricingResultDto resultDto = resultDtoFuture.get();
        order.setProdTotalPrice(resultDto.getOriginalTotalPrice());
        order.setTotalPrice(resultDto.getTotalPrice());
        order.setFreight(resultDto.getFreight());
        order.setBalanceDeductionTotal(resultDto.getBalanceDeductionTotal());
        order.setPointDeductionTotal(resultDto.getPointDeductionTotal());
        order.setCouponDeductionTotal(resultDto.getCouponDeductionTotal());
        // 订单项价格
        List<OrderItem> itemList = new ArrayList<>();
        for (OrderCreateItemForm formItem : orderFormItems) {
            OrderItemPricingResultDto itemResultDto = resultDto.getPrice(formItem.getProdId());
            OrderItem item = new OrderItem();
            item.setProdId(formItem.getProdId());
            item.setQuantity(formItem.getQuantity());
            item.setOriginalPrice(itemResultDto.getOriginalPrice());
            item.setDealPrice(itemResultDto.getPrice());
            item.setOriginalSubTotal(itemResultDto.getOriginalSubTotal());
            item.setDealSubTotal(itemResultDto.getSubTotal());
            itemList.add(item);
        }
        // 发票信息
        Invoice invoice = new Invoice();
        invoice.setContentType(orderForm.getInvoiceContentType());
        invoice.setEmail(orderForm.getInvoiceEmail());
        invoice.setPhone(orderForm.getInvoicePhone());
        invoice.setTitle(orderForm.getInvoiceTitle());
        invoice.setTitleType(orderForm.getInvoiceTitleType());
        invoice.setUserId(currentUser.getUid());

        try {
            orderService.create(order, itemList, invoice);
        } catch (Exception e) {
            throw new OrderCreateException(e);
        }

        return RestResponse.ok(order.getId());
    }

    @GetMapping(value = "/myorders")
    @NeedLogin
    public RestResponse myorders(
            @RequestParam(value = "cp" , defaultValue = "1" , required = false) Long cp
    ) throws Exception {
        CurrentUser currentUser = Applications.getCurrentUser();
        PageContext.setCurrentPage(cp);
        PageContext.setPageSize(10L);
        PageBean<Order> orderPage = orderService.pageByUser(currentUser.getUid() , cp , 10L);
        List<Order> orders = orderPage.getData();
        for(Order order : orders){
            List<OrderItem> orderItemList = orderItemService.listByUserOrder(currentUser.getUid(), order.getId());
            order.setItems(orderItemList);
        }
        return RestResponse.ok(orders);
    }

    @RequestMapping(value = "/myorders/{orderId}", method = RequestMethod.GET)
    @NeedLogin
    public RestResponse orderDetail(@PathVariable String orderId) throws Exception {
        CurrentUser currentUser = Applications.getCurrentUser();
        Order order = orderService.getOrderByUser(currentUser.getUid(), orderId);
        List<OrderItem> orderItemList = orderItemService.listByUserOrder(currentUser.getUid(), orderId);
        order.setItems(orderItemList);
        return RestResponse.ok(order);
    }

    @RequestMapping(value = "/cancelOrder", method = RequestMethod.GET)
    @NeedLogin
    public String cancel(@RequestParam(value = "orderId") String orderId) throws Exception {
        CurrentUser currentUser = Applications.getCurrentUser();
        int count = orderService.cancel(currentUser.getUid(), orderId);
        if (count > 0) {

        }
        return "redirect:user/myorders";
    }

    /**
     * 订单确认
     *
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/checkout")
    @NeedLogin
    public RestResponse checkout() throws Exception {
        CurrentUser currentUser = Applications.getCurrentUser();
        // 获取订单确认项
        CompletableFuture<List<OrderCheckoutItem>> checkoutItems = cartServiceClient.getCheckoutItems(currentUser);
        List<OrderCheckoutItem> orderCheckoutItems = checkoutItems.get();

        OrderPricingDto orderPricingDto = new OrderPricingDto();
        for (OrderCheckoutItem checkoutItem : orderCheckoutItems) {
            OrderItemPricingDto itemPricingDto = new OrderItemPricingDto();
            itemPricingDto.setProdId(checkoutItem.getProdId());
            itemPricingDto.setQuantity(checkoutItem.getQuantity());
            orderPricingDto.addItem(itemPricingDto);
        }
        CompletableFuture<OrderPricingResultDto> dtoCompletableFuture = pricingServiceClient.calculateOrder(currentUser , orderPricingDto);
        OrderPricingResultDto calculateResultDto = dtoCompletableFuture.get();

        for (OrderCheckoutItem checkoutItem : orderCheckoutItems) {
            OrderItemPricingResultDto itemPricingResultDto = calculateResultDto.getPrice(checkoutItem.getProdId());
            checkoutItem.setProdId(checkoutItem.getProdId());
            checkoutItem.setQuantity(checkoutItem.getQuantity());
            checkoutItem.setPrice(itemPricingResultDto.getPrice());
            checkoutItem.setOriginalSubTotal(itemPricingResultDto.getOriginalSubTotal());
            checkoutItem.setSubTotal(itemPricingResultDto.getSubTotal());
            checkoutItem.setPromotions(calculateResultDto.getPromotion(checkoutItem.getProdId()));
        }

        OrderCheckout orderCheckout = new OrderCheckout();
        orderCheckout.setItems(orderCheckoutItems);
        orderCheckout.setSavedMoney(calculateResultDto.getSavedMoney());
        orderCheckout.setTotalPrice(calculateResultDto.getTotalPrice());
        orderCheckout.setOriginalTotalPrice(calculateResultDto.getOriginalTotalPrice());
        orderCheckout.setTotalQuantity(calculateResultDto.getProdTotalQuantity());
        return RestResponse.ok(orderCheckout);
    }

    /**
     * 使用优惠劵
     *
     * @return
     * @throws Exception
     */
//    @PostMapping(value = "/order_useBenefits")
//    @NeedLogin
//    public AjaxResponse useBenefits(@RequestBody OrderForm orderForm) throws Exception {
//        AjaxResponse resp = new AjaxResponse();
//        SessionUser su = redisService.getSessionUser(getUserKey());
//        User user = userService.load(su.getUid());
//        Coupon coupon = null;
//        if (StringHelper.isNotEmpty(orderForm.getUsedCouponId())) {
//            coupon = couponService.myCoupon(su.getUid(), orderForm.getUsedCouponId());
//        }
//        Order order = orderService.calculateFromMyCart(user, coupon, orderForm.getUsedPoints(), orderForm.getUsedBalance());
//
//		resp.putData("originalOrderTotal", result.getOriginalOrderTotal());
//		resp.putData("discountedOrderTotal", result.getDiscountedOrderTotal());
//		resp.putData("couponDeductionPrice", result.getCouponDeductionAmount());
//        return resp;
//    }
}
